<?php
  /**
   * 请谨慎操作文件！
   * 常见的错误造成
   * ·编辑错误的文件
   * ·被垃圾数据填满硬盘
   * ·意外删除文件内容
   */
  trait File
  {
      public function testFile(){

        /**
         * windows VS Linux
         * 当在 Unix 平台上规定路径时，正斜杠 (/) 用作目录分隔符。
         * 而在 Windows 平台上，正斜杠 (/) 和反斜杠 (\) 均可使用。
         * 所有读写函数均有句柄参数,关于句柄未加研究
         * 因此，句柄和指针其实是两个截然不同的概念。
         * windows系统用句并标记系统资源，用句并隐藏系统信息。
         * 你只需要知道有这个东西，然后去调用它就行了，它是32bit的uint。
         * 指针则标记某个物理内存的地址，是不同的概念。
         */
        $file = fopen('test.txt','r+b');

        //umask() 函数改变当前的 umask。
        //注释：在多线程的服务器上尽量避免使用这个函数。创建文件后要改变其权限最好还是使用 chmod()。使用 umask() 会导致并发程序和服务器发生不可预知的情况，因为它们使用相同的 umask。
        //windows可能不太好使
        echo '<br/>'.fileperms("test.txt");
        $old = umask(0);
        echo '<br/>'.fileperms("test.txt");
        chmod("test.txt", 0755);
        echo '<br/>'.fileperms("test.txt");
        umask($old);
        echo '<br/>'.fileperms("test.txt");
        return;

        // echo $name = basename(__FILE__);
        // echo '<br/>'.fileperms($name);
        // echo '<br/>'.umask(0);
        // echo '<br/>'.fileperms($name);
        return;

        //touch() 函数设置指定文件的访问和修改时间。
        //如果文件不存在，则会被创建。后两参默认均是当前系统时间
        date_default_timezone_set('Asia/Shanghai');
        touch('touch.txt');
        echo date('H:i:s a',fileatime('touch.txt'));
        echo '<br/>'.date('H:i:s a',filectime('touch.txt'));
        echo '<br/>'.date('H:i:s a',filemtime('touch.txt'));
        return;


        /**
         * 二者区别,tmpfile()创建的文件会在关闭后（用 fclose()）自动被删除，或当脚本结束后。
         * tempnam(),需要手动删除
         * tmpfile() 无参数 返回文件指针
         */

        //tmpfile() 函数以读写（w+）模式建立一个具有唯一文件名的临时文件。
        echo $temp = tmpfile();
        fwrite($temp, "Testing, testing.");
            //倒回文件的开头
        rewind($temp);
        echo '<br/>'.fread($temp,1024);
        return;

        //tempnam() 函数创建一个具有唯一文件名的临时文件。
        //tmp 临时文件后缀名
        echo $tmp = tempnam('./','test.tmp');
        echo '<br/>'.unlink($tmp);
        return;

        //symlink() 函数创建符号连接。本函数未在 Windows 平台下实现。

        //set_file_buffer() 函数设置打开文件的缓冲大小。
            //无缓冲流
        set_file_buffer($file,0);
        fclose($file);
        return;

        //rmdir() 函数删除空的目录。
        var_dump(mkdir('delete'));
        var_dump(rmdir('delete'));
        return;

        // rewind() 函数将文件指针的位置倒回文件的开头。
        $file = fopen('test.html','r+b');
        echo ftell($file);
        fseek($file,'17');
        echo '<br/>'.ftell($file);
        rewind($file);
        echo '<br/>'.ftell($file);
        return;
        //rename()重命名目录或文件
        echo rename('test.txt','testUpdate.txt');
        echo rename('testUpdate.txt','test.txt');
        return;

        //realpath()返回文件绝对路径
        echo realpath('test.txt');
        return;

        //readlink() 函数返回符号连接指向的目标,windows不能用

        //popen() 函数打开进程文件指针。(执行这个文件)
        $pfile = popen('test.txt','r');
        pclose($pfile);
        return;

        //pathinfo() 函数以数组的形式返回文件路径的信息。
        $this->pri(pathinfo('./upload'));
        return;

        //parse_ini_file() 函数解析一个配置文件，并以数组的形式返回其中的设置。
        $result = parse_ini_file("D:\phpStudy\php\php-7.0.12-nts\php.ini");
        $this->pri($result);
        return;

        echo "
        <form class='' action='' method='post' enctype='multipart/form-data'>
          <input type='file' name='file' value=''>
          <input type='submit' name='submit' value='submit'>
        </form>
        ";

        //move_uploaded_file() 函数将上传的文件移动到新位置。
        //注释：本函数仅用于通过 HTTP POST 上传的文件。
        if (@$_POST['submit'] == 'submit') {
          $this->pri($_FILES);
          var_dump(is_uploaded_file($_FILES['file']['tmp_name']));
          echo chmod('upload',0777);
          $path = './upload/'.basename($_FILES['file']['name']);
          //※※※别TM用中文文件名※※※
          var_dump(move_uploaded_file($_FILES['file']['tmp_name'],$path));
        }
        return;

        //创建目录  windows666
        echo mkdir('mkdir');
        return;

        /**
         * lstat() 函数返回关于文件或符号连接的信息。
         * 提示：本函数与 stat() 函数相同，不同之处只有一点：
         * 如果 file 参数是符号连接的话，
         * 则该符号连接的状态被返回，而不是该符号连接所指向的文件的状态。
         */

        $this->pri(lstat('test.txt'));
        return;

        //linkinfo() 函数返回连接的信息。本函数不能工作在 windows 平台上。

        //link() 函数建立一个硬连接。本函数不能工作在 windows 平台上。

        // is_writeable()	is_writable() 的别名。
        var_dump(is_writeable('test.txt'));
        return;

        //is_uploaded_file() 函数判断指定的文件是否是通过 HTTP POST 上传的。
        var_dump(is_uploaded_file('test.txt'));
        return;

        //is_readable() 函数判断指定文件名是否可读。
        var_dump(is_readable('test.txt'));
        return;

        //is_link() 函数判断指定文件名是否为一个符号连接。
        //ln -s 源位置 目标位置 即司建立符号连接
        clearstatcache();
        var_dump(is_link('test.txt'));
        clearstatcache();
        var_dump(is_link('D:\phpStudy\WWW\mianshiti\internship_tp\index.php'));
        clearstatcache();
        var_dump(is_link('link.lnk'));
        return;

        //is_file() 函数检查指定的文件名是否是正常的文件。
        clearstatcache();
        var_dump(is_file('test.txt'));
        clearstatcache();
        var_dump(is_file('.git'));
        return;

        //is_executable() 函数检查指定的文件是否可执行。
        clearstatcache();
        var_dump(is_executable('test.txt'));
        clearstatcache();
        var_dump(is_executable('.git'));
        chmod('executable.exe',0777);
        clearstatcache();
        var_dump(is_executable('executable.exe'));
        return;

        //检测参数是否是目录[注意目录等级]
        clearstatcache();
        var_dump(is_dir('test.txt'));
        clearstatcache();
        var_dump(is_dir('.git'));
        return;

        //glob() 函数返回匹配指定模式的文件名或目录
        $this->pri(glob('*.txt'));
        return;

        //ftruncate()截断文件至指定长度
        //支持append模式,write模式要借助fseek()???
        $file = fopen('test.txt','a+b');
        echo filesize('test.txt');
        ftruncate($file,40);
            //※※※清空缓存，再次检查文件大小
        clearstatcache();
        echo '<br/>'.filesize('test.txt');

        $file2 = fopen('test.txt','w+b');
        echo '<br/>'.filesize('test.txt');
        ftruncate($file,30);
            //※※※清空缓存，再次检查文件大小
        clearstatcache();
        echo '<br/>'.filesize('test.txt');
        return;

        //同下,返回关于文件的信息[参数是文件名]
        $this->pri(stat('test.txt'));
        return;

        //【fstat】返回关于打开文件的信息[参数只接受句柄],windows视乎不好使
        $this->pri(fstat($file));
        return;

        //ftell返回文件指针的当前位置
        echo ftell($file);
        fgets($file);
        echo '<br/>'.ftell($file);
        return;

        //fseek() 函数在打开的文件中定位。
            //读一行
        echo fgets($file);
            //指针归0(头)
        fseek($file,0);
            //想再读下一行
        echo '<br/>'.fgets($file);
        return;

        //fscanf() 函数根据指定的格式对来自打开的文件的输入进行解析。
        $handle = fopen("fscanf.txt", "r");
        while ($userinfo = fscanf($handle, "%s\t%s\t%s\n")) {
            list ($name, $profession, $countrycode) = $userinfo;
            //... do something with the values
        }
        echo $name,$profession,$countrycode;
        return;

        //fputs,fwrite的别名

        //fputcsv将数据以csv格式数据写入文件,二参为数组
        $arr = array('a','b','c');
        fputcsv($file,$arr);
        return;

        //fpassthru() 函数输出文件指针处的所有剩余数据。
        $file2 = fopen('test.txt','a+b');
            // fwrite($file,'write');
        fpassthru($file2);
        return;

        //fnmatch() 函数根据指定的模式来匹配文件名或字符串。
        //重要事项：目前该函数无法在 Windows 或其它非 POSIX 兼容的系统上使用。
        echo fnmatch('*.txt','test.txt');
        return;

        /**
         * 锁定或释放文件
         * 二参lock可能只：
         * 要取得共享锁定（读取的程序），将 lock 设为 LOCK_SH（PHP 4.0.1 以前的版本设置为 1）。
         * 要取得独占锁定（写入的程序），将 lock 设为 LOCK_EX（PHP 4.0.1 以前的版本中设置为 2）。
         * 要释放锁定（无论共享或独占），将 lock 设为 LOCK_UN（PHP 4.0.1 以前的版本中设置为 3）。
         * 如果不希望 flock() 在锁定时堵塞，则给 lock 加上 LOCK_NB（PHP 4.0.1 以前的版本中设置为 4）。
         */

        $file = fopen('test.txt','r+b');
        echo flock($file,LOCK_UN);
        echo '<br/>'.flock($file,LOCK_UN);
            //fclose也可关闭
        //fclose();
        return;

        /**
         * 返回文件类型
         * 可能的返回值
         * fifo
         * char
         * dir
         * block
         * link
         * file
         * unknown
         */
        echo filetype('test.txt');
        return;

        //返回文件大小
        echo filesize('test.txt').'b';
        return;

        //返回文件的inode编号
          //unix/linux系统内部不使用文件名，而使用inode号码来识别文件。
        echo fileinode('test.txt');
        return;

        //filemtime() 函数返回文件内容上次的修改时间
        date_default_timezone_set('Asia/Shanghai');
        clearstatcache();
        echo date('Y-m-d l H:i:s a',filemtime('test.txt'));
        return;

        //filectime()返回上次文件被【修改】的时间
        date_default_timezone_set('Asia/Shanghai');
        clearstatcache();
        echo date('Y-m-d l H:i:s a',filectime('test.txt'));
        return;

        //fileatime()返回上次文件被【访问】的时间
        date_default_timezone_set('Asia/Shanghai');
        clearstatcache();
        echo date('Y-m-d l H:i:s a',fileatime('test.txt'));
        return;

        //将字符写入文件,三参加入FILE_APPEND,不覆盖加入
        echo file_put_contents('test.txt','file_put_contents',FILE_APPEND);
        echo fread($file,1024*1024);
        return;

        //将文件写入字符串
        echo file_get_contents('test.txt');
        return;

        //检查文件或目录是否存在
        var_dump(file_exists('text.txt'));
        var_dump(file_exists('test.txt'));
        return;

        //将文件读入【数组】
        $this->pri(file('test.txt'));
        return;

        //fgetss按行读取,并过滤掉HTML的PHP
        //二参长度可选
        $file = fopen('test.html','r+b');
        // while (!feof($file)) {
        //   echo fgetss($file);
        // }
        // echo fgetss($file,1024);
        echo fgetss($file,1024*10,'<html>,<script>');
        fclose($file);
        return;

        //读取一行文本,找出csv格式字段,解析并返回数组
        //csv特殊文本格式 xxx，xxx，xxx
        $file = fopen('csv.csv','r+b');
        $this->pri(fgetcsv($file));
        fclose($file);
        return;

        //fgetc()读取单个字符
        $file = fopen('test.txt','r+b');
        echo fgetc($file);
        echo fgetc($file);
        echo fgetc($file);

        while (!feof($file)) {
          echo fgetc($file);
        }
        return;

        //将缓冲的输出写入文件,??没整明白??
        $file = fopen('test.txt','r+b');
        $file2 = fopen('write.txt','a+b');
        echo '输出';
        while (!feof($file)) {
          echo '<br/>'.fgets($file);
        }
        echo '<br/>'.fflush($file2);
        fclose($file);
        fclose($file2);
        return;

        //从文件指针中读取一行。二参length
        $file = fopen('write.txt','r+b');
        while (!feof($file)) {
          echo '<br/>'.fgets($file);
        }
        fclose($file);
        return;

        //feof 监测文件指针是否指向文件尾
        $file = fopen('test.txt','w+b');
        var_dump(feof($file));
        fclose($file);

        $file2 = fopen('write.txt','a+b');
            //读取一行才指向文件尾
        fgets($file2);
        var_dump(feof($file2));
        fclose($file2);
        return;

        /**
         * fopen
         * b和t的使用 见w3c
         * w/w+方式不要随便用,会把文件内容截为0
         */
            //只读打开,文件指针指向头
        // $file = fopen('test.txt','rb');
            //读写打开,指针指向头
        // echo chmod('test.txt',0777);
        // $file = fopen('test.txt','r+b');
        // fwrite($file,'balabala');
            //写入打开,指针指向头,不存在则创建
        // $file = fopen('write.txt','wb');
        // echo fwrite($file,'balabala');
        // echo '<br/>'.chmod('write.txt',0777);
        // unlink('write.txt');    //权限不够 就是删不掉
            //读写打开,指针指向头,不存在则创建
        // $file = fopen('write.txt','w+b');
        // echo fwrite($file,'balabala');
        // echo '<br/>'.chmod('write.txt',0777);
        // unlink('write.txt');    //权限不够 就是删不掉
            //写入打开,指针指向尾,不存在则创建
        // $file = fopen('write.txt','ab');
        // echo fwrite($file,'continue balabala');
            //读写打开,指针指向尾,不存在则创建
        // $file = fopen('write.txt','a+b');
        // echo fwrite($file,'continue balabala');
            //创建并写入打开,指针指向头,如果文件已存在，调用失败并返回 FALSE，并生成一条 E_WARNING 级别的错误信息。
        // $file = fopen('xWrite.txt','xb');
        // echo fwrite($file,'xWrite');
            //创建并读写打开,指针指向头,如果文件已存在，调用失败并返回 FALSE，并生成一条 E_WARNING 级别的错误信息。
        // $file = fopen('xWrite.txt','x+b');
        // echo fwrite($file,'xWrite');
        return;

        //fwrite ,第三参length.覆盖写入(不覆盖用a[add]打开)

        //fread读取,二参指定读取字节数,超出就读到EOF
        $file = fopen('test.txt','r');
        echo fread($file,'1024');
        fclose($file);
        return;

        //fclose,关闭fopen、fsockopen

        //返回指定目录磁盘总大小
        echo (disk_total_space(getcwd())/1024/1024/1024).'GB';
        return;

        //返回目录中可用空间
        echo getcwd();
        echo '<br/>'.(disk_free_space(getcwd())/1024/1024/1024).'GB';
            //别名而已
        echo '<br/>'.(diskfreespace(getcwd())/1024/1024/1024).'GB';
        return;

        //返回文件名的【目录部分】
        echo dirname('http://www.w3school.com.cn/php/func_filesystem_dirname.asp');
        return;

        //删除文件,delete、unset函数消失
            //var_dump(delete('test_bak.txt'));
        echo unlink('test_bak.txt');
            // echo unset('test_bak.txt');
        return;

        /**
         * 拷贝文件
         * ※若目标文件已存在会被覆盖
         */
        echo copy('test.txt','test_bak.txt');
        echo '<br/>'.copy('http://172.104.101.57/internship_tp/index.php','server.php');
        return;

        //改变文件所有者
            //显示文件所有者
        echo fileowner("test.txt");
        chown('test.txt','zxy');
        echo '<br/>'.fileowner("test.txt");
        return;

        /**
         * 获取文件权限
         * 改变文件权限,注意此函数是※※※※四个参数444※※※※
         * 第一个数字永远是 0
         * 第二个数字规定所有者的权限
         * 第二个数字规定所有者所属的用户组的权限
         * 第四个数字规定其他所有人的权限
         */
        clearstatcache();
        echo fileperms('test.txt');
        echo '<br/>'.chmod('test.txt',0777);
        clearstatcache();
        echo '<br/>'.fileperms('test.txt');
        return;

        //改变用户组
        echo chgrp("test.txt","admin");
            //清除文件状态缓存。
        clearstatcache();
            //显示用户组
        echo filegroup('test.txt');
        return;

        //basename() 函数返回路径中的【文件名部分】。
        //二参指定不显示的后缀名
        echo basename('http://www.w3school.com.cn/php/func_filesystem_basename.asp');
        echo '<br/>'.basename('http://www.w3school.com.cn/php/func_filesystem_basename.asp','.asp');
        return;

        //读取文件内容[并把它写入输出流]
        echo readfile('Base.class.php');
        return;
      }
  }

 ?>
